#include "rgb.h"

// 初始化
void RGB_init(void)
{
#if 0 // 寄存器操作
    // 1. RCC配置使能
    // 芯片考虑节能，通常外设默认不提供时钟，降低消耗
    // 因此配置和使用外设前，大多需要配置时钟
    RCC->APB2ENR |= (1 << 3);

    // 2. 控制寄存器CR
    // GPIOB_ODR：
    //  （1）亮灯：bit5/0/1设置为0
    //  （2）灭灯：bit5/0/1设置为1
    // 红灯PB5
    GPIOB->CRL &= ~(0x0f << (5 * 4)); // 先将4个bit置为0
    GPIOB->CRL |= (0x01 << 5 * 4); // 再将对应设为1
    GPIOB->ODR |= (0x01 << 5); // 手动将其默认输出设置为1

    // 绿灯PB0
    GPIOB->CRL &= ~(0x0f << (0 * 4));
    GPIOB->CRL |= (0x01 << 0 * 4);
    GPIOB->ODR |= (0x01 << 0);

    // 蓝灯PB1
    GPIOB->CRL &= ~(0x0f << (1 * 4));
    GPIOB->CRL |= (0x01 << 1 * 4);
    GPIOB->ODR |= (0x01 << 1);

#else // 函数操作
    // 0. RCC配置使能
    RCC->APB2ENR |= (1 << 3);

    // 1. 先准备初始化结构体
    GPIO_InitTypeDef gpio_initStruct;
    // 1.1 设置为推挽输出（Push-Pull Output）
    // 推挽输出可以直接输出高电平（1）或低电平（0）
    // 适用于普通数字信号输出（控制 LED、继电器）
    gpio_initStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    // 1.2 设置传输速度
    // 速度越快，波形越不稳，因此，在满足需求的情况下，选择低速的
    gpio_initStruct.GPIO_Speed = GPIO_Speed_2MHz;
    // 1.3 设置引脚
    gpio_initStruct.GPIO_Pin = RGB_Pin_red | RGB_Pin_green | RGB_Pin_blue;

    // 2. 初始化GPIO
    GPIO_Init(RGB_Port, &gpio_initStruct);

    // 3. 初始设置为输出高
    GPIO_SetBits(RGB_Port, RGB_Pin_red);
    GPIO_SetBits(RGB_Port, RGB_Pin_green);
    GPIO_SetBits(RGB_Port, RGB_Pin_blue);

#endif
}
// 控制灯光颜色
void RGB_redOn(void)
{
    // 将bit5改成0
    // GPIOB->ODR &= ~(0x01 << 5); // 寄存器操作
    // GPIOB->BSRR = 0x01 << (5 + 16);
    // GPIOB->BSRR = RGB_Pin_red << 16;
    // GPIOB->BRR = RGB_Pin_red;
    GPIO_ResetBits(RGB_Port, RGB_Pin_red);
}
void RGB_redOff(void)
{
    // GPIOB->ODR |= (0x01 << 5);
    // GPIOB->BSRR = 0x01 << 5;
    // GPIOB->BSRR = RGB_Pin_red;
    GPIO_SetBits(RGB_Port, RGB_Pin_red);
}
void RGB_greenOn(void)
{
    // GPIOB->ODR &= ~(0x01 << 0);
    GPIO_ResetBits(RGB_Port, RGB_Pin_green);
}
void RGB_greenOff(void)
{
    // GPIOB->ODR |= (0x01 << 0);
    GPIO_SetBits(RGB_Port, RGB_Pin_green);
}
void RGB_blueOn(void)
{
    // GPIOB->ODR &= ~(0x01 << 1);
    GPIO_ResetBits(RGB_Port, RGB_Pin_blue);
}
void RGB_blueOff(void)
{
    // GPIOB->ODR |= (0x01 << 1);
    GPIO_SetBits(RGB_Port, RGB_Pin_blue);
}
void RGB_allOn(void)
{
    // GPIOB->BSRR = (RGB_Pin_red | RGB_Pin_green | RGB_Pin_blue) << 16;
    // 如果需要设置某个或者某些引脚为低，只需要设置BRR对应的引脚为1，其他引脚为0
    GPIOB->BRR = (RGB_Pin_red | RGB_Pin_green | RGB_Pin_blue);
}
void RGB_allOff(void)
{
    // 如果需要设置某个或者某些引脚为高，只需要设置BSRR对应的引脚为1，其他引脚为0
    GPIOB->BSRR = (RGB_Pin_red | RGB_Pin_green | RGB_Pin_blue);
}

// 红灯翻转
void RGB_redToggle(void)
{
    // ^ 异或符号，相同为0，不同为1
    RGB_Port->ODR ^= RGB_Pin_red;
}
